(*--------------------------------------------------------
    Holt                  http://coderesearchlabs.com/holt
    by Javier Santo Domingo (j-a-s-d@coderesearchlabs.com)
  --------------------------------------------------------
    architechture
  --------------------------------------------------------*)

unit holt_architecture;

interface

{$I holt_defines.inc}

uses
  holt_types;

type
  ThEmitterGetName = function: pchar; cdecl;
  ThEmitterGetLevelKinds = function(_level: cardinal): pchar; cdecl;
  ThEmitterSetDestination = function(_destination: pchar): pchar; cdecl;
  ThEmitterBeginEmission = function: pchar; cdecl;
  ThEmitterEndEmission = function: pchar; cdecl;
	ThEmitterEmitNode = function(_level, _position, _childCount: cardinal;
    _path, _kind, _name, _value: pchar): pchar; cdecl;

  IhTreeNode = interface
    // general
    function AsCommands: gString;
    function AsText: gString;
    function IsRoot: gBoolean;
    function GetRoot: IhTreeNode;
    function GetInfo: gString;
    function GetPath: gString;
    function GetLevel: gNumber;
    function GetPosition: gNumber;
    function Search(const AText: gString): gString;
    // fields
    function GetName: gString;
    function GetValue: gString;
    function GetKind: gString;
    procedure SetName(const AName: gString);
    procedure SetValue(const AValue: gString);
    procedure SetKind(const AKind: gString);
    // family
    function GetParent: IhTreeNode;
    procedure SetParent(ANode: IhTreeNode);
    function IncludeChild(AChildNode: IhTreeNode): gBoolean;
    function ExcludeChild(AParentNode: IhTreeNode): gBoolean;
    function GetNamedChild(const AName: gString): IhTreeNode;
    function GetChild(AIndex: gNumber): IhTreeNode;
    function GetChildNodesCount: gNumber;
    procedure ClearChildNodes;
    procedure FlipChildNodes;
    function UpNamedChild(const AName: gString): gBoolean;
    function DownNamedChild(const AName: gString): gBoolean;
    function GetChildPosition(ANode: IhTreeNode): gNumber;
  end;

  IhTree = interface
    // tree nodes related
    function Drop: gBoolean;
    function Rebase: gBoolean;
    function AsCommands: gString;
    function AsText: gString;
    function Search(const AText: gString): gString;
    // nodes navigation related
    function GetNodeByPath(const APath: gString): IhTreeNode;
    function GotoPath(const APath: gString): gBoolean;
    function GotoChild(const AChildName: gString): gBoolean;
    function GotoParent: gBoolean;
    function GotoRoot: gBoolean;
    function GetPath: gString;
    // current node related
    function AddChild(const AName: gString): gBoolean;
    function DeleteChild(const AName: gString): gBoolean;
    function SetName(const AName: gString): gBoolean;
    function SetValue(const AValue: gString): gBoolean;
    function SetKind(const AKind: gString): gBoolean;
    function GetInfo: gString;
    function Truncate: gBoolean;
    function Flip: gBoolean;
    function UpChild(const AName: gString): gBoolean;
    function DownChild(const AName: gString): gBoolean;
    function GetLevel: gNumber;
    function GetCurrentNode: IhTreeNode;
  end;

  IhEmissionAPI = interface
    function GetName: gString;
    function GetLevelKinds(ALevel: gNumber): gString;
    function SetDestination(const ADestination: gString): gBoolean;
    function BeginEmission: gBoolean;
    function EndEmission: gBoolean;
	  function EmitNode(ALevel, APosition, AChildCount: gNumber;
      const APath, AKind, AName, AValue: gString): gBoolean;
  end;

  IhEmitter = interface(IhEmissionAPI)
    procedure Initialize(const AEmitterFile: gString);
    function Load: gBoolean;
    procedure Unload;
    procedure Reset;
    procedure Disable;
    function IsReady: gBoolean;
    function GetReadinessStatus: gString;
    function GetLastResult: gString;
    function Emit(ATree: IhTree; const ADestination: gString): gBoolean;
  end;

  IhEmissionController = interface
    function LoadEmitter(const AEmitterFile: gString): gBoolean;
    function ReloadEmitter(const AEmitterName: gString): gBoolean;
    function SetCurrentEmitter(const AEmitterName: gString): gBoolean;
    function GetCurrentEmitter: IhEmitter;
    function GetEmittersList: gString;
  end;

  IhReportBuilder = interface
    function AsPrompt(const APath: gString): gString;
    function AsError(const AMessage: gString = ''): gString;
    function AsMultiline(const ATitle, ABody: gString): gString;
    function AsLine(const ATitle, ABody: gString): gString;
    function AsKindsForLevel(AEmitter: IhEmitter; ALevel: gNumber): gString;
  end;

  IhExecutionBridge = interface
    function ExecuteCommand(const ACommand: gString): gBoolean;
  end;

  ThRegisters = record
    ExecutionBridge: IhExecutionBridge;
    EmissionController: IhEmissionController;
    ReportBuilder: IhReportBuilder;
    Tree: IhTree;
    Flags: record
      Debug: boolean;
      Parameters: gBoolean;
      Quit: gBoolean;
    end;
    Command: record
      Raw: gString;
      Opcode: gChar;
      Parameters: gString;
      Result: gString;
    end;
  end;

  ThInstructionRun = function(var ARegisters: ThRegisters): gString;

  ThInstruction = record
    Opcode: gChar;
    Run: ThInstructionRun;
  end;

  IhInstructionsSelector = interface
    function FetchByOpcode(AOpcode: gChar): ThInstruction;
  end;

  IhProcessor = interface
    function Execute(
      AEmissionController: IhEmissionController;
      AReportBuilder: IhReportBuilder;
      ATree: IhTree;
      const ACommand: gString
    ): gBoolean;
    function GetLastResult: gString;
  end;

  IhCore = interface
    procedure RunBatchMode(const AParam: gString);
    procedure RunInteractiveMode;
  end;

implementation

end.
